const fs = require("fs");
const path = require('path');


/**
 * 保存文件
 * @param filePath
 * @param data
 */
export const saveFile = function (filePath: string, data: any): boolean {
    filePath = path.resolve(filePath);
    const p = filePath.split("\\");
    if (p.length < 2) {
        console.warn("no filename in file path");
        return false;
    }
    const filename = p.pop();
    const tp = [];
    while (p.length) {
        tp.push(p.shift());
        const tPath = tp.join("\\");
        if (!fs.existsSync(tPath)) {
            fs.mkdirSync(tPath);
        }
    }
    tp.push(filename);
    fs.writeFileSync(tp.join("\\"), data);
    return true;
};

/**
 * 删除文件
 * @param filePath
 */
export const deleteFile = function (filePath: string): boolean {
    filePath = path.resolve(filePath);
    if (!fs.existsSync(filePath)) {
        return true;
    }
    try {
        fs.unlinkSync(filePath);
        return true;
    } catch (e) {
        return false;
    }
}

/**
 * 新建文件夹
 * @param filePath
 */
export const mkDir = function (filePath: string) {
    try {
        filePath = path.resolve(filePath);
        const p = filePath.split("\\");
        const tp = [];
        while (p.length) {
            tp.push(p.shift());
            const tPath = tp.join("\\");
            if (!fs.existsSync(tPath)) {
                fs.mkdirSync(tPath);
            }
        }
        return true;
    } catch (e) {
        return false;
    }

}

// 目录属性结构
export class DirTree {

    constructor(name, path, pathArray, isFile, children = [],
                birthTime = null, modifiedTime = null, key = "",
                parentPath = "",
    ) {
        this.name = name;
        this.rename = name;
        this.path = path;
        this.isFile = isFile;
        this.pathArray = pathArray;
        this.children = children;
        this.birthTime = birthTime;
        this.modifiedTime = modifiedTime;
        this.key = key;
        this.parentPath = parentPath;
    }

    name: string;
    rename: string;
    path: string;
    parentPath: string;
    key: string;
    pathArray: string[];
    isFile: boolean;
    children: DirTree[];
    birthTime: string;
    modifiedTime: string;
    gitAddress: string = "";
}

/**
 * 递归目录，得到目录所有文件和文件夹索引
 * @param dir           目标目录
 * @param pathArray     累计目录层
 * @param excludes      排除文件或文件夹名称
 * @param recursive     是否无线递归（false 仅仅遍历 dir 目录）
 * @param onlyDir       只查找文件夹
 * @param parentPath
 */
export const recursiveDirectory = function (
    dir: string, pathArray: string[] = [], excludes: string[],
    recursive: boolean = true, onlyDir: boolean = false
):
    DirTree[] {
    const pDir = path.resolve(dir);
    const res = [];
    if (!fs.existsSync(pDir)) {
        return [];
    }
    const list = fs.readdirSync(pDir);
    list.forEach(d => {
        if (excludes.includes(d)) return;
        const fp = pathArray.concat(d), fd = path.join(dir,d);
        const stat = fs.statSync(path.join(dir, d));
        const birthTime = stat.birthtime, modifiedTime = stat.mtime;
        const key = dir + '-' + d + '-' + (stat.isDirectory() ? 'dir' : 'file');
        if (stat.isDirectory()) {
            res.push(new DirTree(
                d, fd, fp, false,
                recursive ? recursiveDirectory(fd, fp, excludes, recursive, onlyDir,) : [], birthTime, modifiedTime,
                key, dir
            ));
        } else if (stat.isFile() && !onlyDir) {
            res.push(new DirTree(
                d, fd, fp, true, [], birthTime, modifiedTime, key, dir
            ));
        }
    });
    return res;
}

/**
 * 递归删除非空文件夹
 * @param dirPath
 */
export const deleteFolderRecursive = (dirPath) => {
    dirPath = path.resolve(dirPath);
    if (fs.existsSync(dirPath)) {
        fs.readdirSync(dirPath).forEach(function (file) {
            let curPath = path.join(dirPath, file); // dirPath + "/" + file;
            if (fs.statSync(curPath).isDirectory()) { // recurse
                deleteFolderRecursive(curPath);
            } else { // delete file
                fs.unlinkSync(curPath);
            }
        });
        fs.rmdirSync(dirPath);
    }
}

/**
 * 移动文件
 * @param source
 * @param target
 */
export const moveFile = (source, target) => {
    try {
        fs.renameSync(source, target);
        return true;
    } catch (e) {
        return false;
    }
}

/**
 * 复制文件
 * @param source
 * @param target
 */
export const copyFile = (source, target) => {
    try {
        const readStream = fs.createReadStream(source);
        const writeStream = fs.createWriteStream(target);
        readStream.pipe(writeStream);
        return true;
    } catch (e) {
        return false;
    }
}